#include "wpgraphicslistitem.h"
#include "busyindicator.h"
#include "themedatastorage.h"

#include <QGraphicsSceneMouseEvent>
#include <QPoint>
#include <QRect>
#include <QKeyEvent>
#include <QPainter>
#include <QGraphicsLayout>
#include <QStyleOptionGraphicsItem>
#include <QLinearGradient>

#include <qdrawutil.h>

WPGraphicsListItem::WPGraphicsListItem(BusyIndicator& aBusyIndicator, ThemeData& aThemeData)
    : iThemeData(aThemeData)
    , iBusyX(0)
    , iBusyY(0)
    , iCol1ContentXOffset(0)
    , iTimerId(0)
    , iBusyIndicator(aBusyIndicator)
    , iHasMenuFocus(false)
{
    /* Size can not be set here, as the virtual table is not initialized,
     * and it would end up in the resize function
     */
    setFocusPolicy(Qt::StrongFocus);
    setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed);
    setContentsMargins(0, 0, 0, 0);
}

void WPGraphicsListItem::mousePressEvent(QGraphicsSceneMouseEvent *e)
{
    QGraphicsWidget::mousePressEvent(e);
    e->accept();
}

void WPGraphicsListItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *e)
{
    if (hasFocus())
    {
        emit Selected(this);
    }
    QGraphicsWidget::mouseReleaseEvent(e);
}

void WPGraphicsListItem::keyPressEvent(QKeyEvent *e)
{
    if (e->key() == Qt::Key_Select || e->key() == Qt::Key_Enter)
    {
        emit Selected(this);
        e->accept();
    }
    else
    {
        QGraphicsWidget::keyPressEvent(e);
    }
}

void WPGraphicsListItem::resizeEvent(QGraphicsSceneResizeEvent *e)
{
    prepareGeometryChange();
    iBoundingRect.setSize(e->newSize());
    
    // Busy indicator
    const QPixmap& px = iBusyIndicator.PixmapToDraw();
    iBusyX = (int)iBoundingRect.width()/2 - px.width()/2;
    iBusyY = (int)iBoundingRect.height()/2 - px.height()/2;
    
    // XXX fix
    iCol1ContentXOffset = 13;
    
    handleGeomeryChange();
    updateGeometry();
}

QPointF WPGraphicsListItem::TopRight() const
{
    return geometry().topRight();
}

QRectF WPGraphicsListItem::boundingRect() const
{
    return iBoundingRect;
}

void WPGraphicsListItem::MarkBogusFocus(bool aActive)
{
    iHasMenuFocus = aActive;
}

bool WPGraphicsListItem::BogusFocus()
{
    return iHasMenuFocus;
}

void WPGraphicsListItem::paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget)
{
    painter->setPen(Qt::NoPen);   

    drawBackground(painter);
    drawBorder(painter);

    // Deriving class stuff
    //painter->setClipRect(option->exposedRect, Qt::IntersectClip);
    paintContent(painter, option, widget);

    // States
    if (iTimerId != 0)
    {
        killTimer(iTimerId);
        iTimerId = 0;
    }

    if (IsBusy())
    {
        painter->setPen(Qt::NoPen);
        painter->setBrush(QColor(0, 0, 0, 128));
        painter->drawRect(boundingRect());
        painter->setBrush(QColor(0,0,0));
        painter->drawPixmap(QPoint(iBusyX,iBusyY), iBusyIndicator.PixmapToDraw());
        iTimerId = startTimer(300);
    }
    else if (HasError())
    {
        QFont errorFont("Arial");
        errorFont.setBold(true);
        errorFont.setPixelSize(24);
        painter->setFont(errorFont);
        painter->setPen(Qt::red);
        painter->drawText(int(boundingRect().topRight().x()-25),int(boundingRect().topRight().y()+30),QString("!"));
    }
}

void WPGraphicsListItem::drawBackground(QPainter * painter)
{
    QRectF rect(iBoundingRect.adjusted(0.0, 1.0, 0.0, 0.0));
    
    if (hasFocus() || iHasMenuFocus) {
        QColor color = QColor(255,255,255);
        painter->setBrush(color);
        painter->drawRect(rect);
    } else {
        QLinearGradient gradient(0.5, 0.0, 0.5, 1.0);
        gradient.setCoordinateMode(QGradient::ObjectBoundingMode);
        gradient.setColorAt(0.0, QColor(241, 241, 241));
        gradient.setColorAt(1.0, QColor(214, 214, 214));
        
        QBrush brush(gradient);
        painter->fillRect(rect, brush);
    }
}

void WPGraphicsListItem::drawBorder(QPainter * painter)
{
    QPen pen(QColor(179, 179, 179)); // Move to theme data
    pen.setWidth(1);
    painter->setPen(pen);
    
    QLine line(iBoundingRect.bottomLeft().x(), iBoundingRect.bottomLeft().y(),
               iBoundingRect.bottomRight().x(), iBoundingRect.bottomRight().y());
    painter->drawLine(line);
}

void WPGraphicsListItem::timerEvent(QTimerEvent*)
{
    update();
}
